import { Controller, Get, Post, Logger } from '@nestjs/common';
import { bundle } from '@remotion/bundler';
import { getCompositions, renderMedia } from '@remotion/renderer';
import * as path from 'path';
import * as fs from 'fs';

@Controller()
export class AppController {
  private readonly logger = new Logger(AppController.name);
  private bundlePromise: Promise<string> | null = null;

  constructor() {
    // 确保必要的目录存在
    const dirs = [
      './output',
      './node_modules/.cache',
      './node_modules/.cache/webpack',
    ];

    dirs.forEach((dir) => {
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
      }
    });
  }

  // 复用 bundle 实例
  private async getBundled() {
    if (!this.bundlePromise) {
      try {
        this.bundlePromise = bundle(
          path.resolve('./src/remotion/Video.tsx'),
          (progress) => {
            this.logger.log(`Bundle progress: ${Math.round(progress * 100)}%`);
          },
          {
            webpackOverride: (config) => {
              return {
                ...config,
                cache: {
                  type: 'filesystem',
                  cacheDirectory: path.resolve('./node_modules/.cache/webpack'),
                },
              };
            },
          },
        );
      } catch (error) {
        this.logger.error('Bundle 创建失败:', error);
        throw error;
      }
    }
    return this.bundlePromise;
  }

  @Get('test')
  getTest() {
    return { message: 'Test API is working!' };
  }

  @Post('render-video')
  async renderVideo() {
    const requestId = Math.random().toString(36).substr(2, 9);
    const startTime = Date.now();
    this.logger.log(`开始渲染视频 [${requestId}]...`);

    try {
      // 使用共享的 bundle
      const bundled = await this.getBundled();

      // 获取组合信息
      const compositions = await getCompositions(bundled);
      const composition = compositions.find((c) => c.id === 'MyVideo');

      if (!composition) {
        throw new Error('找不到视频组合');
      }

      // 渲染视频
      const outputPath = path.resolve(
        `./output/video-${Date.now()}-${requestId}.mp4`,
      );

      await renderMedia({
        composition,
        serveUrl: bundled,
        codec: 'h264',
        outputLocation: outputPath,
      });

      const endTime = Date.now();
      const duration = (endTime - startTime) / 1000;

      this.logger.log(`视频渲染完成 [${requestId}]，耗时: ${duration}秒`);
      return {
        message: '视频渲染完成',
        outputPath,
        duration: `${duration}秒`,
        requestId,
      };
    } catch (error) {
      this.logger.error(`视频渲染失败 [${requestId}]:`, error);
      throw error;
    }
  }

  @Post('render-video-full')
  async renderVideoFull() {
    const startTime = Date.now();
    this.logger.log('开始渲染视频...');

    // 创建webpack打包
    const bundled = await bundle(path.resolve('./src/remotion/Video.tsx'));

    // 获取组合信息
    const compositions = await getCompositions(bundled);
    const composition = compositions.find((c) => c.id === 'MyVideo');

    if (!composition) {
      throw new Error('找不到视频组合');
    }
    // 渲染视频
    const outputPath = path.resolve(
      `./output/video-${Date.now()}-${Math.random().toString(36).substr(2, 9)}.mp4`,
    );

    await renderMedia({
      composition,
      serveUrl: bundled,
      codec: 'h264',
      outputLocation: outputPath,
    });

    const endTime = Date.now();
    const duration = (endTime - startTime) / 1000; // 转换为秒

    this.logger.log(`视频渲染完成1，耗时: ${duration}秒`);
    return {
      message: '视频渲染完成',
      outputPath,
      duration: `${duration}秒`,
    };
  }
}
